#include <iostream>
#include <csignal>
// 系统调用的头文件，因为系统是用C写的，所以他们模仿标准库都以.h结尾了
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

void notice(int signal)
{
    std::cout << getpid() << " get a signal:" << signal << std::endl;
    int i = 1;
    sleep(5); // 先等子进程全部
    while (true)
    {
        // int status = 0;
        // pid_t rpid = waitpid(-1, &status, 0);
        // if (rpid > 0)
        // {
        //     std::cout << "wait chlid process " << rpid << ", 序号：" << i << std::endl;
        // }
        // else if (rpid == -1) // 说明没有子进程了 (阻塞等待)
        // {
        //     std::cout << "wait child success done " << std::endl;
        //     break;
        // }
        int status = 0;
        pid_t rpid = waitpid(-1, &status, WNOHANG);
        if (rpid > 0)
        {
            std::cout << "wait chlid process " << rpid << ", 序号：" << i << std::endl;
        }
        else if (rpid == -1) // 说明没有子进程了 (阻塞等待/非阻塞等待)
        {
            std::cout << "wait child success done, no child process" << std::endl;
            break;
        }
        else // rpid == 0 //没有退出的子进程了，非阻塞等待
        {
            std::cout << "wait child success done " << std::endl;
            break;
        }

        i++;
    }
}
void Dootherthing()
{
    std::cout << "Dootherthing" << std::endl;
}
int main()
{
    // 信号自定义捕捉
    struct sigaction act, oldact;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = notice;
    sigaction(SIGCHLD, &act, &oldact);
    // 创建子进程
    for (size_t i = 1; i <= 5; i++)
    {
        pid_t rpid = fork();
        if (rpid == 0)
        {
            // child
            std::cout << "I am child process, pid:" << getpid() << "->" << i << std::endl;
            sleep(5); // n秒后子进程全被创建出，再统一退出
            exit(1);
        }
    }
    // father
    while (true) // 让父进程循环起来不结束，否则会出现，父进程结束了，子进程还没结束的现象
    {
        Dootherthing();
        sleep(1);
    }

    return 0;
}